package org.akomantoso.core.io.util.torefactor;

import java.io.IOException;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

import org.akomantoso.core.data.AmendmentContent;
import org.akomantoso.core.data.AmendmentHeading;
import org.akomantoso.core.data.AmendmentJustification;
import org.akomantoso.core.data.AmendmentReference;
import org.akomantoso.core.data.group.AmendmentBlock;
import org.akomantoso.core.io.Input;
import org.akomantoso.core.io.InputConstants;
import org.akomantoso.core.io.util.Instantiator;

/**
 * 
 * @author <a href="mailto:jacques.militello@gmail.com">Jacques Militello</a>
 * 
 */
public final class AmendmentBlockUtil {

	private AmendmentBlockUtil() {
	}

	static final Map<String, Instantiator<AmendmentBlock>> ITEMS = new IdentityHashMap<String, Instantiator<AmendmentBlock>>();

	public static void read(Input in, List<AmendmentBlock> elements) throws IOException {

		AmendmentBlock element = null;
		final String localName = in.getLocalName();

		int evenType;
		while (true) {
			evenType = in.readNext();
			switch (evenType) {
			case InputConstants.START_ELEMENT:
				elements.add(element = instantiate(in.getLocalName()));
				element.readExternal(in);
				break;
			case InputConstants.END_ELEMENT:
				if (localName == in.getLocalName().intern()) {
					return;
				}
			}
		}
	}

	static AmendmentBlock instantiate(String elementName) {

		final Instantiator<AmendmentBlock> instatiator = ITEMS.get(elementName);
		if (instatiator == null) {
			throw new RuntimeException("Tag [" + elementName + "] not supported for AmendmentsElement ?!?");
		}
		return instatiator.instantiate();

	}

	static {

		// amendmentHeading
		ITEMS.put(AmendmentHeading.ELEMENT.intern(), new Instantiator<AmendmentBlock>() {
			public AmendmentHeading instantiate() {
				return new AmendmentHeading();
			}
		});

		// amendmentContent
		ITEMS.put(AmendmentContent.ELEMENT.intern(), new Instantiator<AmendmentBlock>() {
			public AmendmentContent instantiate() {
				return new AmendmentContent();
			}
		});
		
		// amendmentReference
		ITEMS.put(AmendmentReference.ELEMENT.intern(), new Instantiator<AmendmentBlock>() {
			public AmendmentReference instantiate() {
				return new AmendmentReference();
			}
		});
		
		// amendmentJustification
		ITEMS.put(AmendmentJustification.ELEMENT.intern(), new Instantiator<AmendmentBlock>() {
			public AmendmentJustification instantiate() {
				return new AmendmentJustification();
			}
		});

	}

}